﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BIZMA._controls;
using BIZModel;
using BL.BIZControls;
using System.Web.Security;
using BIZMA.BL.Security;

namespace BIZMA._controls.Security
{
    public partial class List_ObjectRoles : BIZListControl, IBIZControlDefaultMethods
    {
        #region Default
        public void DefaultListLoad()
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// Hämta alla användare/grupper som har roller kopplad till objektet (tex Folders)
        /// </summary>
        /// <param name="Id">ObjectId ex FolderId</param>
        /// <param name="loadByType">ObjectTypeName ex objfolder.GetType().FullName (BIZModel.Folder). Måste finnas motsvarande sträng (TypeString) sparad i ObjectTypes tabellen</param>
        public void DefaultListLoad(Guid Id, string loadByType)
        {
            LoadObjectRoles(Id, loadByType);
        }

        public void DefaultEditNew()
        {
            throw new NotImplementedException();
        }

        public void DefaultEditNew(Guid Id, string editByType)
        {
            throw new NotImplementedException();
        }

        public void DefaultEditLoad(Guid Id)
        {
            throw new NotImplementedException();
        }

        #endregion

        
        //Properties för att hålla reda på om en dialog kan öppnas eller om den redan är öppen i en underliggande dialog
        private bool CanAddRoles { get { return ViewState["CanAddRoles"] != null ? (bool)ViewState["CanAddRoles"] : true; } set { ViewState["CanAddRoles"] = value; } }

        //OLIKA ID properties som styr frågan för listan tex om man ska hämta utifrån EmployeeId eller PlanningId
        //Styrs av publika metoder
        private Guid ObjectId { get { return ViewState["ObjectId"] != null ? (Guid)ViewState["ObjectId"] : Guid.Empty; } set { ViewState["ObjectId"] = value; } }
        private string ObjectTypeString { get { return ViewState["ObjectTypeString"] != null ? (string)ViewState["ObjectTypeString"] : ""; } set { ViewState["ObjectTypeString"] = value; } }
        public Guid ObjectTypeId { get { return ViewState["ObjectTypeId"] != null ? (Guid)ViewState["ObjectTypeId"] : Guid.Empty; } set { ViewState["ObjectTypeId"] = value; } }


        //Olika filter för frågan till listan kan tex vara om man ska visa alla eller aktiva, eller datum mmm
        //Filter sätter man innan man kör de publika metorder som sätter ID properties som finns ovan
        //--

        //Övriga properties 
        private List<Guid> SelectedGroups { get { if(ViewState["SelectedGroups"] == null) { ViewState["SelectedGroups"] = new List<Guid>();} return (List<Guid>)ViewState["SelectedGroups"]; } set { ViewState["SelectedGroups"] = value; } }
        private List<Guid> SelectedUsers { get { if (ViewState["SelectedUsers"] == null) { ViewState["SelectedUsers"] = new List<Guid>(); } return (List<Guid>)ViewState["SelectedUsers"]; } set { ViewState["SelectedUsers"] = value; } }
        private DataPager _DataPager { get; set; }

        #region Init
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack || !InitLoaded)
            {
                InitLoaded = true;
                FillActionList();
                //Gör sådant som man gör på pageload här typ fyll "statisk" dropdown med värden mm 
                //Väldigt ovanligt att man laddar listan härifrån då det oftast görs via en annan metod se public void LOAD_BY_SOMETHING_LIST(int someval)
             }

            //Event från kontroller i popuper
            if (mcUsers.ContainedListControl != null)
            {
                mcUsers.ContainedListControl.ListSelect += new SelectedChanged(UserSelect);
            }
            if (mcGroups.ContainedListControl != null)
            {
                mcGroups.ContainedListControl.ListSelect += new SelectedChanged(GroupSelect);
            }

        }


        protected override void OnInit(EventArgs e)
        {
                       
            //här gör man alla init inställningar tex lägga till eventhandlers och annat som styr sidan
            //Peka ut dropdown för basklassen
            base.ActionDropDown = ddlAction;
            //Peka ut listkontrollen för basklassne
            base.ListControl = lv;
            //Kör om formpart har fler än 1 rad
            base.SetFormPartHeight(3); //Fieldset räknas som en rad och textarean är mer än en rad 
            //Ingen funktion för att bara välja en rad
            base.MultipleSelect = true;

            base.OnInit(e);

            //Event när basklassen behöver listdatat
            base.NeedsData += new NeedsDataHandler(List_NeedsData);




            if (ContainerControl != null)
            {
                //Titel på Caontainerkontrollen
                ContainerControl.Title = "Kopplade roller";
                //Event vid klick på knapparna i containerkontrollen
                ContainerControl.ButtonsClick += new ButtonsHandler(ContainerControl_ButtonsClick);
                //Vilka knappar som ska visas
                ContainerControl.ShowButtons(true, true, true, false);

                //Om container är en modal dialog
                if (ModalContainerControl != null)
                {
                   
                    ModalContainerControl.Width = 800;
                    ModalContainerControl.Height = 500;
                    //Event om storlek på modalakontrollen ändras kan användas för att justera storlek på andra element i kontrollen
                    ModalContainerControl.FormScrollStyleChanged += new EventHandler(ModalContainerControl_FormScrollStyleChanged);
                }

                CanAddRoles = mcUsers.CanAddPopupControl(BIZControl.UserList) && mcGroups.CanAddPopupControl(BIZControl.GroupList);

                //Sätt validation group från Containercontrollen så de blir unika på sidan
                selRole.ValidationGroup = ContainerControl.ValGroupSave;

            }

            //Event när detaljdialogen stänger
            mcUsers.ModalClosing += new ModalControlClosing(mcUsers_ModalClosing);
            mcGroups.ModalClosing += new ModalControlClosing(mcGroups_ModalClosing);
            mcUsers.UnLoadControlOnClose = true;
            mcGroups.UnLoadControlOnClose = true;

            ListDataBound += new EventHandler<ListViewItemEventArgs>(List_ListDataBound);
            lv.LayoutCreated += new EventHandler(lv_LayoutCreated);



            btnSelGroups.Command += new CommandEventHandler(btnSelGroups_Command);
            btnSelUsers.Command += new CommandEventHandler(btnSelUsers_Command);
        }


     




    

        /// <summary>
        /// Fyller dropdown med värden
        /// </summary>
        private void FillActionList()
        {
            ddlAction.Items.Add(new ListItem("--Välj åtgärd--", "-"));
            ddlAction.Items.Add(new ListItem("Radera", "DEL"));

        }

        /// <summary>
        /// Aktiverar/inaktiverar knappar som behöver data eller som inte kan visas pga underliggande dialoger 
        /// </summary>
        private void ToggleButtons()
        {
            if (CanAddRoles)
            {
                phConnect.Visible = true;
                phHideConnect.Visible = false;
                if (ContainerControl != null)
                {
                    ContainerControl.ShowButtons(true, true, true, false);
                }
            }
            else
            {
                phConnect.Visible = false;
                phHideConnect.Visible = true;
                if (ContainerControl != null)
                {
                    ContainerControl.ShowButtons(false, true, false, false);
                }
            }
        }

        #endregion
        #region Container Events
        /// <summary>
        /// Event när Container ändrar storlek
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ModalContainerControl_FormScrollStyleChanged(object sender, EventArgs e)
        {
            //ListScroll Height sätts automatiskt i basklassen 
        }

        void List_NeedsData(bool sorting)
        {
            LoadList(sorting);
        }

        /// <summary>
        /// Triggas vid klick på någon av containerkontrollens knappar
        /// </summary>
        /// <param name="sender">Containerkontrollen</param>
        /// <param name="actionType">Vilken typ av knapp som klickats</param>
        void ContainerControl_ButtonsClick(object sender, ActionType actionType)
        {
            if (actionType == ActionType.Save || actionType == ActionType.SaveClose)
            {
                Save();
            }
        }


        #endregion

        #region Events This Control
        ///// Event  när man har knappar för att välja en rad i listan
        ///// </summary>
        ///// <param name="sender">Knappen som klickats</param>
        ///// <param name="e">Knappens CommandEventArgs</param>
        //protected void btnSel_Command(object sender, CommandEventArgs e)
        //{
        //    SelectedItems = new List<Guid>();
        //    SelectedItems.Add(Guid.Parse(e.CommandArgument.ToString()));

        //    //Kör denna metod så att containercontrollen kan trigga ett SelectEvent tillbaka till sidan med containern 
        //    CallListSelect(this, null, MultipleSelect, SelectedItems);

        //}
        /// <summary>
        /// Event när man har valt en/flera rader i listan och väljer att utföra något från åtgärdslistan tex (Välj eller radera) 
        /// </summary>
        /// <param name="sender">Knappen utför</param>
        /// <param name="e">EventArgs. Används inte det är vad man valt i ddlAction som är intressant</param>
        protected void btnAction_Click(object sender, EventArgs e)
        {
            if (ddlAction.SelectedValue != "-")
            {


                var selectedKeys = lv.GetSelectedDataKeys("chkSel");
                BIZMAEntities ent = BaseBL.GetEnt();

                if (ddlAction.SelectedValue == "DEL")
                {
                    foreach (DataKey dk in selectedKeys)
                    {                        
                        Guid objectId = Guid.Parse(dk.Values[0].ToString());
                        string objectType = dk.Values[1].ToString();
                        Guid roleId = Guid.Parse(dk.Values[2].ToString());

                        if (objectType == SecurityBL.TYPE_USER)
                        {
                            ObjectUserRoles OUR = ent.ObjectUserRoles.FirstOrDefault(q => q.UserId == objectId && q.RoleId == roleId);
                            ent.DeleteObject(OUR);
                        }
                        else if (objectType == SecurityBL.TYPE_GROUP)
                        {
                            ObjectGroupRole OGR = ent.ObjectGroupRoles.FirstOrDefault(q => q.UserGroupId == objectId && q.RoleId == roleId);
                            ent.DeleteObject(OGR);
                        }
                    }
                }

                ent.SaveChanges();
               
            }

            LoadList(false);

        }

        ///// <summary>
        ///// Event för klick på sökfunktionen
        ///// </summary>
        ///// <param name="sender">Knappen</param>
        ///// <param name="e">Knappens EventArgs</param>
        //protected void btnSearch_Click(object sender, EventArgs e)
        //{
            

        //    LoadList(true);
        //}

     
        #endregion


        #region Control and List methods
        /// <summary>
        /// Här rensas alla id properties som används för frågan till listan
        /// </summary>
        private void ResetIdProperties()
        {
            ObjectId = Guid.Empty;
            ObjectTypeString = "";
            ObjectTypeId = Guid.Empty;
            SelectedGroups = null;
            SelectedUsers = null;

            lv.DataSource = null;
            lv.DataBind();
        }
        /// <summary>
        /// Hämta alla användare/grupper som har roller kopplad till objektet (tex Folders)
        /// </summary>
        /// <param name="objectId">ObjectId ex FolderId</param>
        /// <param name="objectTypeName">ObjectTypeName ex objfolder.GetType().FullName (BIZModel.Folder). Måste finnas motsvarande sträng (TypeString) sparad i ObjectTypes tabellen</param>
        public void LoadObjectRoles(Guid objectId, string objectTypeName)
        {
            ResetIdProperties();
            ObjectId = objectId;
            ObjectTypeString = objectTypeName;

            BIZMAEntities ent = BaseBL.GetEnt();

            ObjectTypes OT = ent.ObjectTypes.FirstOrDefault(q => q.TypeString == ObjectTypeString);

            if (OT != null)
            {
                ObjectTypeId = OT.ObjectTypeId;
            }
            else
            {
                throw new ArgumentException("Det finns ingen objekttyp registrerad för detta objekt (" + ObjectTypeString + "). Kontrollera parameter och konfigurering.", "ObjectTypeString");
            }

            LoadList(true);

        }
        /// <summary>
        /// Nollställ kontrollen och töm listan på värden
        /// </summary>
        public void Clear()
        {
            ResetIdProperties();
        }


        /// <summary>
        /// Metod som ansvarar för att fylla listan med värden utifrån vilken publik load metod som körts innan
        /// </summary>
        /// <param name="sorting">Talar om ifall sortering ska ändras eller om man ska använda tidigare sortering</param>
        private void LoadList(bool sorting)
        {
            InitLoaded = true;

            BIZMAEntities ent = BaseBL.GetEnt();
            ICollection<Security_ObjectRole> query = ent.Security_GetObjectRoles(ObjectId, ObjectTypeString).ToArray();

            if (((object)_DataPager) != null)
            {
                if (query.Count <= _DataPager.StartRowIndex)
                {
                    int newIndex = query.Count - _DataPager.PageSize;

                    if (newIndex < 0)
                        newIndex = 0;

                    _DataPager.SetPageProperties(newIndex, _DataPager.PageSize, true);

                }
            }


            lv.DataSource = query;
            lv.DataBind();
          

            if (!sorting)
                lv.ReSort(ViewState);

            if (SelectedGroups.Count > 0 || SelectedUsers.Count > 0)
            {
                //txtConSelected.ToolTip = txtConSelected.ToolTip.Replace("Inget valt", "");
            }
            else
            {
                txtConSelected.ToolTip = "Inget valt";
                txtConSelected.Text = "";
            }
        }



        /// <summary>
        /// Event för varje rad som laddas i listan
        /// </summary>
        /// <param name="sender">Listan</param>
        /// <param name="e">ListViewItemEventArgs</param>
        void List_ListDataBound(object sender, ListViewItemEventArgs e)
        {

            Literal lit4 = (Literal)e.Item.FindControl("lit4");
            string idType = DataBinder.Eval(e.Item.DataItem, "IdType").ToString();

            lit4.Text = (idType == SecurityBL.TYPE_USER ? "Användare":"Grupp");



        }

        void lv_LayoutCreated(object sender, EventArgs e)
        {
            _DataPager = (DataPager)lv.FindControl("pager");
        }

        /// <summary>
        /// Koppla valda användare/grupper till den roll som är vald
        /// </summary>
        private void Save()
        {

            BIZMAEntities ent = BaseBL.GetEnt();

            Guid roleId = selRole.SelectedId;

            


            if (SelectedGroups.Count > 0)
            {
                foreach (Guid groupId in SelectedGroups)
                {
                    List<ObjectGroupRole> OGRs = ent.ObjectGroupRoles.Where(q => q.ObjectId == ObjectId && q.ObjectTypeId == ObjectTypeId).ToList();

                    ObjectGroupRole OGR = ObjectGroupRole.CreateObjectGroupRole(ObjectId, ObjectTypeId, groupId, roleId);

                    if (OGRs.Exists(q => q.ObjectId == OGR.ObjectId && q.ObjectTypeId == OGR.ObjectTypeId && q.UserGroupId == OGR.UserGroupId && q.RoleId == OGR.RoleId) == false)
                    {
                        ent.ObjectGroupRoles.AddObject(OGR);
                    }
                }
            }

            if (SelectedUsers.Count > 0)
            {
                List<ObjectUserRoles> OURs = ent.ObjectUserRoles.Where(q => q.ObjectId == ObjectId && q.ObjectTypeId == ObjectTypeId).ToList();

                foreach (Guid userId in SelectedUsers)
                {
                    ObjectUserRoles OUR = ObjectUserRoles.CreateObjectUserRoles(ObjectId, ObjectTypeId, userId, roleId);

                    if (OURs.Exists(q => q.ObjectId == OUR.ObjectId && q.ObjectTypeId == OUR.ObjectTypeId && q.UserId == OUR.UserId && q.RoleId == OUR.RoleId)  == false)
                    {
                        ent.ObjectUserRoles.AddObject(OUR);
                    }
                }
            }

            ent.SaveChanges();


            SelectedGroups = null;
            SelectedUsers = null;
            LoadList(false);
        }


        #endregion

        #region detail dialog
        /// <summary>
        /// Klick för att öppna väja användare
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CommandEventArgs</param>
        void btnSelUsers_Command(object sender, CommandEventArgs e)
        {
            if (CanAddRoles)
            {
                //Man kan inte använda AddDefaultListLoad.. när man ska sätta olika properties på kontrollen (PickerControl)
                //mcUsers.AddControl(BIZControl.UserList);
                //if (mcUsers.ContainedControlExists)
                //{
                //    BIZMA._controls.Users.List_Users uc = ((BIZMA._controls.Users.List_Users)mcUsers.ContainedControl);
                //    uc.PickerControl = true;
                //    uc.LoadUsers();
                //    mcUsers.ModalOpen();
                //}

                
                mcUsers.AddDefaultListLoad(BIZControl.UserList,true);



            }
        }
        /// <summary>
        /// Klick för att öppna väja grupper
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">CommandEventArgs</param>
        void btnSelGroups_Command(object sender, CommandEventArgs e)
        {
            if (CanAddRoles)
            {
                mcGroups.AddDefaultListLoad(BIZControl.GroupList, true);

            }
        }

        /// <summary>
        /// Event när rolldialogen stänger
        /// </summary>
        /// <param name="sender">ModalaContainern</param>
        /// <param name="e">EventArgs</param>
        void mcGroups_ModalClosing(object sender, EventArgs e)
        {
            //laddar om när man har sparat
        }
        /// <summary>
        /// Event när rolldialogen stänger
        /// </summary>
        /// <param name="sender">ModalaContainern</param>
        /// <param name="e">EventArgs</param>
        void mcUsers_ModalClosing(object sender, EventArgs e)
        {
            //laddar om när man har sparat
        }


        void GroupSelect(object sender, EventArgs e, bool multipleSelect, List<Guid> selectedItems)
        {
            BIZMAEntities ent = BaseBL.GetEnt();

            foreach (Guid groupId in selectedItems)
            {
                if (SelectedGroups.Contains(groupId) == false)
                {
                    SelectedGroups.Add(groupId);

                    txtConSelected.Text += ent.UserGroups.FirstOrDefault(q => q.UserGroupId == groupId).Name + "; ";
                }
            }

        }

        void UserSelect(object sender, EventArgs e, bool multipleSelect, List<Guid> selectedItems)
        {
            BIZMAEntities ent = BaseBL.GetEnt();

            foreach (Guid userId in selectedItems)
            {
                if (SelectedUsers.Contains(userId) == false)
                {
                    SelectedUsers.Add(userId);

                    UserProfile UP = ent.UserProfiles.FirstOrDefault(q => q.UserId == userId);

                    txtConSelected.Text += UP.FirstName + " " + UP.LastName + "; ";
                }
            }


        }

        #endregion


    }
}